from django.shortcuts import render
from django.views import View
from django.http import JsonResponse
from django_redis import get_redis_connection
from users.models import User
from django.contrib.auth import login, authenticate, logout
from ihome.utils.views import LoginRequiredJsonMixin
from ihome.libs.qiniu_demo import QiNiu
from django.db import transaction
from django.utils import timezone
from ihome.utils.image_check import image_checking
import json, re, logging

logger = logging.getLogger('ihome')

url = "http://qs930d3tn.hn-bkt.clouddn.com/"


class RegisterView(View):
    """注册"""

    def post(self, request):
        # 1. 接收参数
        json_dict = json.loads(request.body.decode("utf-8"))
        mobile = json_dict.get("mobile")
        phonecode = json_dict.get("phonecode")
        password = json_dict.get("password")

        # 2. 校验参数
        if not all([mobile, phonecode, password]):
            return JsonResponse({"errno": 4002, "errmsg": "缺少必要参数"})
        # 验证手机号是否合法
        if not re.fullmatch('1[3-9]\d{9}', mobile):
            return JsonResponse({"errno": 4002, "errmsg": "mobile参数有误"})
        # 验证手机号是否重复注册
        if User.objects.filter(mobile=mobile).count() > 0:
            return JsonResponse({"errno": 4003, "errmsg": "该手机号已经注册"})
        # 校验短信验证码
        redis_conn = get_redis_connection('verify_code')
        sms_code = redis_conn.get("sms_%s" % mobile)
        if sms_code is None:
            return JsonResponse({"errno": 4002, "errmsg": "短信验证码失效"})
        if sms_code.decode("utf-8") != phonecode:
            return JsonResponse({"errno": 4004, "errmsg": "短信验证码有误"})

        # 3. 业务数据处理
        try:
            user = User.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile,
                avatar="ihome/users/avatar/default",   # 用户默认头像
            )
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4004, "errmsg": "注册失败"})
        login(request, user)

        # 4. 响应返回
        return JsonResponse({"errno": 0, "errmsg": "注册成功"})


class LoginView(View):
    """登录、判断是否登录、退出登录"""

    # 登录
    def post(self, request):
        # 1. 提取参数
        json_dict = json.loads(request.body.decode("utf-8"))
        mobile = json_dict.get("mobile")
        password = json_dict.get("password")

        # 2. 校验参数
        if not all([mobile, password]):
            return JsonResponse({"errno": 4002, "errmsg": "缺少必要参数"})
        if not re.fullmatch('^1[3-9]\d{9}', mobile):
            return JsonResponse({"errno": 4002, "errmsg": "mobile参数有误"})

        # 3. 业务处理
        user = authenticate(request, username=mobile, password=password)
        if user is None:
            return JsonResponse({"errno": 4102, "errmsg": "用户名或者密码错误"})
        login(request, user)

        # 4. 响应返回
        return JsonResponse({"errno": 0, "errmsg": "登录成功"})

    # 判断是否登录
    def get(self, request):
        user = request.user

        if not user.is_authenticated:
            return JsonResponse({"errno": 4101, "errmsg": "未登录"})
        user_model = User.objects.get(id=user.id)

        return JsonResponse(
            {"errno": 0, "errmsg": "已登录", "data": {"user_id": user_model.id, "name": user_model.username}})

    # 退出登录
    def delete(self, request):
        logout(request)
        response = JsonResponse({"errno": 0, "errmsg": "已登出"})
        response.delete_cookie("sessionid")
        return response


class UserCenterView(LoginRequiredJsonMixin, View):
    """个人中心"""

    def get(self, request):
        user = request.user
        user_model = User.objects.get(id=user.id)

        avatar_url = url + str(user_model.avatar)
        data = {
            "avatar": avatar_url,
            "create_time": user_model.date_joined.strftime('%Y-%m-%d %H-%M-%S'),
            "mobile": user_model.mobile,
            "name": user_model.username,
            "user_id": user_model.id
        }

        return JsonResponse({"errno": 0, "errmsg": "OK", "data": data})


class UploadAvatarView(LoginRequiredJsonMixin, View):
    """用户上传个人头像"""

    def post(self, request):
        # 1. 接收参数
        user = request.user
        avatar = request.FILES.get("avatar")  # 获取图片

        # 2. 校验参数
        # 校验图片是否上传
        if avatar is None:
            return JsonResponse({"errno": 4002, "errmsg": "缺少参数"})
        # 校验上传文件是否时图片
        if image_checking(avatar) is None:
            return JsonResponse({"errno": 4002, "errmsg": "图片格式不正确"})

        # 3. 业务处理
        user_id = user.id
        # 拼接头像上传到七牛云中的文件名
        key_str = "ihome/users/avatar/" + str(user_id) + "/" + timezone.localtime().strftime('%Y%m%d%H%M%S')

        # TODO：先删除原头像再上传新头像，使用事务进行操作
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                user_model = User.objects.get(id=user_id)
                # 删除原头像
                if user_model.avatar != "ihome/users/avatar/default":
                    QiNiu().delete(user_model.avatar)
                # 上传新头像
                avatar_byte = avatar.read()  # 将图片转换成byte
                image_url = QiNiu().upload_data(key_str, avatar_byte)
                user_model.avatar = image_url
                user_model.save()
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return JsonResponse({"errno": 4003, "errmsg": "头像上传失败"})
        transaction.savepoint_commit(save_id)

        # 4. 响应返回
        avatar_url = url + image_url
        return JsonResponse({
            "errno": 0,
            "errmsg": "头像上传成功",
            "data": {
                "avatar_url": avatar_url
            },
        })


class UpdateUsernameView(LoginRequiredJsonMixin, View):
    """用户名修改"""

    def put(self, request):
        # 1. 提取参数
        user = request.user
        json_dict = json.loads(request.body.decode("utf-8"))
        name = json_dict.get("name")

        # 2. 校验参数
        if name is None:
            return JsonResponse({"errno": 4002, "errmsg": "缺少参数"})

        # 3. 业务处理
        try:
            User.objects.filter(id=user.id).update(username=name)
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4004, "errmsg": "修改失败"})

        # 4. 响应返回
        return JsonResponse({"errno": 0, "errmsg": "修改成功"})


class RealNameView(LoginRequiredJsonMixin, View):
    """用户实名认证"""

    # 进行实名认证
    def post(self, request):
        # 1. 提取参数
        user = request.user
        json_dict = json.loads(request.body.decode("utf-8"))
        real_name = json_dict.get("real_name")
        id_card = json_dict.get("id_card")

        # 2. 校验参数
        if not all([real_name, id_card]):
            return JsonResponse({"errno": 4002, "errmsg": "缺少必传参数"})
        if not re.fullmatch(
                "([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]",
                id_card):
            return JsonResponse({"errno": 4004, "errmsg": "id_card参数有误"})

        # TODO:这里假装通过第三方验证了身份证和姓名的真实性

        # 3. 业务处理
        try:
            user.real_name = real_name
            user.id_card = id_card
            user.save()
        except Exception as e:
            logger.error(e)
            return JsonResponse({"errno": 4003, "errmsg": "实名认证信息保存失败"})

        # 4. 响应返回
        return JsonResponse({"errno": 0, "errmsg": "认证信息保存成功"})

    # 显示实名认证信息
    def get(self, request):
        user = request.user
        data = {"real_name": user.real_name, "id_card": user.id_card}
        return JsonResponse({"errno": 0, "errmsg": "获取成功", "data": data})


